package model;

import java.util.ArrayList;
import java.util.Observable;

import physics.Angle;
import physics.Circle;
import physics.Geometry;
import physics.LineSegment;
import physics.Vect;
import physics.Geometry.DoublePair;

public class Board extends Observable {
	
	private int L;
	private IGizmo[][] grid;
	private LineSegment[] walls;
	private Vect reflection;
	
	
	public Board(int L) {
		this.L = L;
		grid = new IGizmo[20][20];
		
		walls = new LineSegment[4];
		walls[0] = new LineSegment(0, 0, 0, L*20);
		walls[1] = new LineSegment(0, L*20, L*20, L*20);
		walls[2] = new LineSegment(L*20, L*20, L*20, 0);
		walls[3] = new LineSegment(L*20, 0, 0, 0);
	}

	public boolean addGizmo(IGizmo gizmo, int x, int y) {
		if((x >= 0 && x <= 19) && (y >= 0 && y <= 19)) {
			grid[x][y] = gizmo;
			gizmo.setPosition(x, y);
			update();
			return true;
		}
		return false;
	}
	
	public int getL() {
		return L;
	}
	
	public LineSegment[] getWalls() {
		return walls;
	}
		
	public ArrayList<IGizmo> getGizmos() {
		ArrayList<IGizmo> gizmos = new ArrayList<IGizmo>();
		
		for (int i=0 ; i <= 19 ; i++) {
			for (int j=0 ; j <= 19 ; j++) {
				if (grid[i][j] != null)
					gizmos.add(grid[i][j]);
			}
		}
		return gizmos;
	}
	
	public IGizmo getGizmo(int x, int y) {
		if((x >= 0 && x <= 19) && (y >= 0 && y <= 19)){
			System.out.println(grid[x][y]);
			return grid[x][y];}
		else 
			return null;
	}
	
	public double timeUntilCollision(Ball ball) {
		double time=Double.POSITIVE_INFINITY, temp=0;
		
		for (LineSegment line : walls) {
			temp = Geometry.timeUntilWallCollision(line, ball.getCircle(), ball.getV());
			if (temp < time) {
				time = temp;
				reflection = Geometry.reflectWall(line, ball.getV()); 
			}
		}
		return time;
	}

	public Vect reflectionVector(Ball ball) {
		return reflection;
	}
	
	public void clear() {
		for (int i=0 ; i <= 19 ; i++) {
			for (int j=0 ; j <= 19 ; j++)
				grid[i][j] = null;
		}
		this.setChanged();
		this.notifyObservers();
	}
	
	public void removeGizmo(int x, int y) {
		if((x >= 0 && x <= 19) && (y >= 0 && y <= 19)) {
				grid[x][y] = null;
				update();
		}
	}
	
	public void update() {
		this.setChanged();
		this.notifyObservers();
	}
	
	
	public void setL(int gridL) {
		L = gridL;
		update();
	}
	
	
	public static void main(String[] args) {
//
//		Board board = new Board();
//		IGizmo gizmo = new Square(board.getL());
//		 
//		boolean test = board.addGizmo(gizmo, 0, 0);
//		System.out.println(test);
//		
//		test = board.addGizmo(gizmo, 0, 2313);
//		System.out.println(test);
//		
//		Circle circle = new Circle(board.getL());
//		test = board.addGizmo(circle, 5, 3);
//		System.out.println(test);
//		
//		System.out.println(board.getGizmos().size());
//		
//		Vect temp = new Vect(Angle.DEG_270, 10);
//		System.out.println(temp);
		
//		physics.Circle circle = new Circle(0, 0, 1); 
//		LineSegment line = new LineSegment(0, 10, 10, 0);
//
//		Vect v = new Vect(Angle.DEG_45, 1);
//		System.out.println(Geometry.timeUntilWallCollision(line, circle, v) +", " +v);
//		
//		Ball ball = new Ball(25);
//		physics.Circle circle = new Circle(481, 481, 25);
//		
//		System.out.println(circle);
//		System.out.println(ball.getCircle());
//		
//		LineSegment line = new LineSegment(475, 0, 500, 25);
//		Vect v = new Vect(Angle.DEG_270, 10);		
//		
//		System.out.println(Geometry.timeUntilWallCollision(line, circle, v));
//		System.out.println(Geometry.timeUntilWallCollision(line, ball.getCircle(), v));
		
//		Vect v = new Vect(Angle.DEG_180, 2);
//		Vect g = new Vect(Angle.DEG_90, 6);
//		System.out.println(v);
//		System.out.println(g);
//		System.out.println(g.projectOn(v));		
//		System.out.println(g.angle().minus(v.angle()).radians());
		

		System.out.println(-1 * Math.PI);
		System.out.println(-1 * Math.PI/2);
		System.out.println(Math.PI);
		
		System.out.println(Math.toRadians(10));
		
	}	

}
